package com.kuizii.auth.shiro;

import com.kuizii.auth.JWTToken;
import com.kuizii.auth.util.AuthUtils;
import com.kuizii.demo.api.SysUserService;
import com.kuizii.demo.domain.SysUserDto;
import lombok.extern.slf4j.Slf4j;
import org.apache.shiro.authc.*;
import org.apache.shiro.authz.AuthorizationException;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.authz.Permission;
import org.apache.shiro.authz.SimpleAuthorizationInfo;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.subject.PrincipalCollection;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.StringUtils;

import java.util.HashSet;
import java.util.Set;

/**
 * shiro Realm
 *
 * @author jameszhou
 */

/**
 * 无状态realm
 */
@Slf4j
public class KuiziiStatelessRealm extends AuthorizingRealm {

    /**
     * 用户服务
     */
    @Autowired
    SysUserService userService;


    /**
     * 大坑！，必须重写此方法，不然Shiro会报错
     * 限定这个Realm只支持我们自定义的JWT Token
     */
    @Override
    public boolean supports(AuthenticationToken token) {
        return token instanceof JWTToken;
    }

    /**
     * 认证
     */
    @Override
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {

        JWTToken userToken = (JWTToken) token;

        AuthUtils.verify(userToken.getToken());

        SimpleAuthenticationInfo info = new SimpleAuthenticationInfo(userToken, userToken, "jwtShiroRealm");
        return info;
    }


    /**
     * 授权
     */
    @Override
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {

        if (principals == null) {
            throw new AuthorizationException("PrincipalCollection method argument cannot be null.");
        }
        if (!(principals.getPrimaryPrincipal() instanceof JWTToken)) {
            return null;
        }
        JWTToken userToken = (JWTToken) principals.getPrimaryPrincipal();
        SysUserDto sysUser = userService.getUserById(userToken.getUserName());

        if (sysUser == null) {
            throw new UnknownAccountException("用户信息不存在！");
        }
        if (sysUser.getUserState() == -1) {
            throw new LockedAccountException("帐户已被禁用！");
        }
        if (StringUtils.isEmpty(sysUser.getPassword())) {
            throw new UnknownAccountException("用户需完善信息！");
        }

        SimpleAuthorizationInfo info = new SimpleAuthorizationInfo();
        //todo
        Set<String> roles = new HashSet<String>(){};
        Set<String> permissions = new HashSet<String>(){} ;
        info.setRoles(roles);
        info.setStringPermissions(permissions);
        return info;
    }


    /**
     * 权限验证
     *
     * @param principals
     * @param permission
     * @return
     */
    @Override
    public boolean isPermitted(PrincipalCollection principals, Permission permission) {
        return super.isPermitted(principals, permission);
    }

    /**
     * 权限验证
     *
     * @param principals
     * @param permission
     * @return
     */
    @Override
    public boolean isPermitted(PrincipalCollection principals, String permission) {
        if (permission.contains("/")) {
            permission = StringUtils.trimLeadingCharacter(permission, '/');

            permission = permission.replace("/", ":");
            if (permission.endsWith(":")) {
                permission += "*";
            }
            if (permission.endsWith("**")) {
                permission = permission.substring(permission.length() - 1);
            }
        }

        return super.isPermitted(principals, permission);
    }
}
